/*
 * sem.c
 *
 *  编写时间: 2021/7/23
 *  编写者: wmh
 *
 */


#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>


typedef union {
    int            val;    /* Value for SETVAL */
    struct semid_ds *buf;    /* Buffer for IPC_STAT, IPC_SET */
    unsigned short  *array;  /* Array for GETALL, SETALL */
    struct seminfo  *__buf;  /* Buffer for IPC_INFO
                                      (Linux-specific) */
} semun;


int sem_init(int key)
{
    int semid;
    semid = semget((key_t)key, 0, 0666);
    if (semid == -1)
    {
        semid = semget((key_t)key, 1, 0666 | IPC_CREAT);

        semun mu;
        mu.val = 1;

        semctl(semid, 0, SETVAL, mu);
    }
    return semid;
}

void sem_p(int id, int sem)
{
    struct sembuf buff;
    buff.sem_num = sem;
    buff.sem_op = -1;
    buff.sem_flg = SEM_UNDO;
    semop(id, &buff, 1);
}

void sem_v(int id, int sem)
{
    struct sembuf buff;
    buff.sem_num = sem;
    buff.sem_op = 1;
    buff.sem_flg = SEM_UNDO;
    semop(id, &buff, 1);
}

void sem_del(int id)
{
    semctl(id, 0, IPC_RMID);
}


